package com.example.everying.service.content.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.everying.constant.ChatMessageConstant;
import com.example.everying.constant.OrderConstants;
import com.example.everying.context.UserContext;
import com.example.everying.framework.websocket.service.WebSocketChatService;
import com.example.everying.framework.websocket.utils.WebSocketRedisUtil;
import com.example.everying.mapper.content.ActivityApplyMapper;
import com.example.everying.mapper.content.ActivityArticleMapper;
import com.example.everying.model.dto.chat.ConversationDto;
import com.example.everying.model.dto.content.ArtInfoDto;
import com.example.everying.model.entity.chat.ChatMessagesEntity;
import com.example.everying.model.entity.content.ActivityApply;
import com.example.everying.model.entity.content.ActivityArticle;
import com.example.everying.model.entity.order.BountyOrder;
import com.example.everying.model.entity.system.SysNotification;
import com.example.everying.model.entity.user.PointsAccount;
import com.example.everying.model.entity.user.UserBalanceEntity;
import com.example.everying.model.entity.user.UserBalanceTransactionEntity;
import com.example.everying.model.entity.user.UserEntity;
import com.example.everying.model.vo.chat.ChatMessageVo;
import com.example.everying.model.vo.content.ActivityApplyVo;
import com.example.everying.model.vo.content.ApplyViewVo;
import com.example.everying.service.chat.ChatConversationService;
import com.example.everying.service.chat.ChatMessagesService;
import com.example.everying.service.chat.impl.RedDotService;
import com.example.everying.service.content.ActivityApplyService;
//import com.example.everying.service.order.OrderInfoService;
import com.example.everying.service.content.ActivityArticleService;
import com.example.everying.service.order.BountyOrderService;
import com.example.everying.service.system.SysNotificationService;
import com.example.everying.service.user.*;
import com.example.everying.utils.CampusException;
import com.example.everying.utils.LocalDateUtils;
import com.example.everying.utils.RandomUtil;
import com.example.everying.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @program: everything
 * @description: 申请人服务层
 * @author: zw
 * @create: 2025-05-16 10:42
 **/
@Slf4j
@Service
public class ActivityApplyServiceImple extends ServiceImpl<ActivityApplyMapper, ActivityApply> implements ActivityApplyService {
    private static final String PLATFORM_USER_ID = "1"; // 平台用户ID
    // 信用值扣分
    private static final double COMPLETE_REWARD = 0.5;  // 按时完成
    private static final double EARLY_QUIT_PENALTY = -0.5; // 3分钟内退出
    private static final double END_QUIT_PENALTY = -1.0; // 句截止时间3小时内
    private static final double TIMEOUT_PENALTY = -0.2;    // 超时完成
    private static final double LATE_QUIT_PENALTY = -0.1;  // 10分钟内退出
    private static final double CREDIT_INCREMENT = 0.1; // 接单人悬赏任务完成加权分

//    @Autowired
//    private OrderInfoService orderInfoService;
    @Autowired
    private ActivityArticleMapper articleMapper;
    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    private UserBalanceTransactionService userBalanceTransactionService;
    @Autowired
    private ChatMessagesService chatMessagesService;
    @Autowired
    private ChatConversationService chatConversationService;
    @Autowired
    private UserService userService;
    @Autowired
    private SysNotificationService notificationService;
    @Autowired
    private WebSocketRedisUtil webSocketRedisUtil;
    @Autowired
    private SysNotificationService sysNotificationService;
    @Autowired
    private UserScoreService userScoreService;
    @Autowired
    private BountyOrderService bountyOrderService;
    @Autowired
    private PointsAccountService pointsAccountService;
    @Autowired
    private ActivityArticleService activityArticleService;
    @Autowired
    private RedDotService redDotService;

    @Override
    public IPage<ActivityApply> selectPage(Page<ActivityApply> pageParam, ActivityApplyVo applyVo) {
        //创建查询wrapper
        ActivityApply content = new ActivityApply();
        BeanUtil.copyProperties(applyVo, content);
        QueryWrapper<ActivityApply> wrapper = new QueryWrapper();
        wrapper.orderByDesc("accepted_at");
        //调用mapper的方法
        IPage<ActivityApply> pages = baseMapper.selectPage(pageParam, wrapper);
        return pages;
    }

    /**
     * @param applyVo
     * @return
     */
    @Override
    @Transactional
    public Result<?> applyAdd(ActivityApplyVo applyVo) {
        UserEntity user = UserContext.getUser();
        if (user == null) {
            return Result.fail("请先登录");
        }
        if (user.getCreditValue() <= 3.0) {
            return Result.fail("您的信用值过低");
        }
        if (applyVo.getArtId() == null) {
            return Result.fail("未找到该帖子");
        }

        String artId = applyVo.getArtId();
        ActivityArticle activityArticle = articleMapper.getArticleById(artId);

        if (activityArticle == null) {
            return Result.fail("未找到该帖子");
        }
        if (activityArticle.getPublicStatus() != 0) {
            return Result.fail("该帖子已下架");
        }
        if (LocalDateUtils.isExpired(activityArticle.getEndTime())) {
            return Result.fail("该帖子已结束");
        }
        // 使用数据库原子操作检查是否已申请
        boolean exists = baseMapper.exists(
                new QueryWrapper<ActivityApply>()
                        .eq("user_id", user.getId())
                        .eq("art_id", applyVo.getArtId())
        );
        if (exists) {
            return Result.fail("您已申请过该帖子，请勿重复申请");
        }

        List<ActivityApply> list = baseMapper.selectList(new QueryWrapper<ActivityApply>().eq("art_id", artId));
        AtomicBoolean isApply = new AtomicBoolean(false);
        list.forEach(apply -> {
            //当前的申请的拒绝记录不能超过2次
            if (apply.getUserId().equals(user.getId()) && apply.getRefuseNum() == 2) {
                isApply.set(true);
            }
            // 判断是否已申请
            if (apply.getOrdersStatus().equals("1") || apply.getOrdersStatus().equals("3")) {
                isApply.set(true);
            }
        });
        if (isApply.get()) {
            return Result.fail("该帖子已申请");
        }
        ActivityApply articleById = baseMapper.getArticleById(artId, user.getId());

        if (articleById != null && articleById.getRefuseNum() == 2) {
            return Result.fail("拒绝次数过多");
        }
        if (articleById == null || articleById.getOrdersStatus().equals("2")) {
            ActivityApply apply = new ActivityApply();
            apply.setId(RandomUtil.generateId());
            apply.setUserId(user.getId());
            apply.setAcceptedAt(LocalDateTime.now());
            //自动接单改变文章状态和接单状态为  进行中
            if (activityArticle.getOrdersType().equals("1")) {
                apply.setOrdersStatus("1");
                activityArticle.setArtViewStatus(2);
                activityArticle.setStatus("1");
                activityArticle.setApplyId(user.getId());
            } else {
                apply.setOrdersStatus("2");
//                activityArticle.setApplyId(user.getId());

            }
            apply.setArtId(applyVo.getArtId());
            apply.setAppViewStatus(2);
            BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
            boolean isHandleOrder = true;
            if (activityArticle.getType() == 1) {
                log.info("用户{}申请成功，开始处理订单", user.getId());
                isHandleOrder = handleOrderApply(apply, applyVo, bountyOrder, activityArticle);
            }
            if (!isHandleOrder) {
                return Result.fail("处理订单失败");
            }
            activityArticle.setArtViewStatus(2);
            activityArticle.setAppealStatus("3");
            boolean aBoolean = this.save(apply);
            articleMapper.updateById(activityArticle);
            if (!aBoolean) {
                return Result.fail("申请失败");
            }
            // 处理订单交易
            String payPassWord = applyVo.getPayPassword() == null ? "" : applyVo.getPayPassword();
            processOrderTransaction(apply, activityArticle, payPassWord, applyVo.getPoints());
            // 官方发送悬赏文章申请通知(通知发布者)
            sendRewardApplicationNotification(apply, activityArticle);
            return Result.ok(apply.getId());
        }
        return Result.fail();
    }

    /**
     * 处理用户接单申请
     *
     * @param apply       申请实体
     * @param applyVo     前端入参
     * @param bountyOrder 订单实体
     * @return Result.ok()  / Result.fail(...)
     */
    private boolean handleOrderApply(ActivityApply apply, ActivityApplyVo applyVo,
                                     BountyOrder bountyOrder, ActivityArticle activityArticle) {

        String userId = apply.getUserId();

        if (applyVo.getPoints() == null) {
            applyVo.setPoints(0);
        }

        // 1. 查余额
        UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
        if (userBalance == null) {
            throw new CampusException("获取用户余额失败", 201);
        }

        // 2. 计算金额
        BigDecimal cashAmount = activityArticle.getMoney();
        BigDecimal pointsAmount;
        if (applyVo.getPoints() != null && applyVo.getPoints() > 0) {
            pointsAmount = BigDecimal.valueOf(applyVo.getPoints()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
            cashAmount = cashAmount.subtract(pointsAmount);
            // 还要判断一下是不是抵扣的超出本身的金额了
            if (cashAmount.compareTo(BigDecimal.ZERO) < 0) {
                throw new CampusException("抵扣积分超出悬赏金额", 201);
            }
            // 4.判断积分够不够
            PointsAccount userPoints = pointsAccountService.getByUid(userId);
            if (userPoints == null) {
                log.info("用户积分账户不存在");
                boolean isCreate = pointsAccountService.createPointsAccount(userId, 0);
                if (!isCreate) {
                    throw new CampusException("创建用户积分账户失败", 201);
                }
            }
            userPoints = pointsAccountService.getByUid(userId);
            // 扣积分
            if (userPoints.getAvailablePoints() < applyVo.getPoints()) {
                log.info("用户积分账户余额不足");
                throw new CampusException("用户积分账户余额不足", 201);
            }
        }

        // 3. 余额校验
        if (userBalance.getAvailableAmount().compareTo(cashAmount) < 0) {
            throw new CampusException(" 余额不足", 201);
        }


//        // 4. 更新订单字段
//        bountyOrder.setAcceptorId(userId);
//        bountyOrder.setOrderStatus(OrderConstants.ORDER_STATUS_ACCEPT);
//        bountyOrder.setCashAmount(cashAmount);
//        bountyOrder.setPoints(applyVo.getPoints());
//        bountyOrder.setPointsAmount(pointsAmount);
//        bountyOrder.setBountyAmount(activityArticle.getMoney());
//        bountyOrder.setUpdateTime(LocalDateTime.now());
//
//        // 5. 落库
//        bountyOrderService.updateById(bountyOrder);

        log.info(" 用户{}申请成功，开始处理订单", userId);
        return true;
    }

    /**
     * @param applyVo
     * @return
     */
    @Transactional
    @Override
    public boolean applyEdit(ActivityApplyVo applyVo) {
        // 相当于审核
        if (applyVo.getId() == null) {
            throw new CampusException("未查询该申请", 201);
        }
        ActivityApply articleApp = baseMapper.selectById(applyVo.getId());
        if (articleApp == null) {
            throw new CampusException("未查询该申请", 201);
        }
        if (articleApp.getArtId() == null) {
            throw new CampusException("未查询该文章", 201);
        }
        ActivityArticle activityArticle = articleMapper.selectById(articleApp.getArtId());
//        ActivityApply articleById = baseMapper.getArticleById(article.getArtId());
        if (activityArticle == null) {
            throw new CampusException("未查询该文章", 201);
        }
        if (articleApp.getUserId().equals(applyVo.getUserId())) {
            throw new CampusException("不能操作自己的申请", 201);
        }
        if (applyVo.getOrdersStatus() == null) {
            throw new CampusException("未查询该申请状态", 201);
        }
        //发布者拒绝申请人文章是"未开始"状态，拒绝次数+1
        if (applyVo.getOrdersStatus().equals("5") && !articleApp.getOrdersStatus().equals("5")) {
            applyVo.setRefuseNum(articleApp.getRefuseNum() + 1);
            activityArticle.setStatus("2");
            applyVo.setAppViewStatus(2);
        }
        //申请"已完成"状态修改结束时间根据此时间判断，帖子不是申诉中才可以已完成
        if (applyVo.getOrdersStatus().equals("3") && !activityArticle.getAppealStatus().equals("0")) {
            applyVo.setEndAt(LocalDateTime.now());
            activityArticle.setArtViewStatus(2);
        }
        //再次申请发布者收到待查看通知
        if (applyVo.getOrdersStatus().equals("2")) {
            activityArticle.setArtViewStatus(2);
        }
        //申请人退出文章状态改为“未开始”
        if (applyVo.getOrdersStatus().equals("4")) {
            activityArticle.setStatus("2");
            //申请人退出提示发布者
            activityArticle.setArtViewStatus(2);
        }
        //手动接单同意申请时改变文章状态为 进行中
        if (applyVo.getOrdersStatus().equals("1")) {
            activityArticle.setStatus("1");
            articleApp.setAppViewStatus(2);
            applyVo.setAppViewStatus(2);
            activityArticle.setApplyId(articleApp.getUserId());
        }
//        article.setOrdersStatus(applyVo.getOrdersStatus());
        //拒绝次数不能超过2次
//        if (articleApp.getRefuseNum() == 2) {
//            throw new CampusException("拒绝次数过多", 201);
//        }
//        processOrderTransaction(applyVo, article, activityArticle);
/*        Double creditValue = handlerCreditValue(applyVo, article, activityArticle);
        applyVo.setCreditValue(creditValue);*/
        // 处理信用值
//        handlerCreditValue(applyVo, articleApp, activityArticle);

        articleMapper.updateById(activityArticle);
        articleApp.setOrdersStatus(applyVo.getOrdersStatus());
        String payPassWord = applyVo.getPayPassword() == null ? "" : applyVo.getPayPassword();
        Integer points = applyVo.getPoints() == null ? 0 : applyVo.getPoints();
        processOrderTransaction(articleApp, activityArticle, payPassWord, points);
        //申请者待查看提醒
        // 发送申请处理结果通知(通知申请者||发布者)
        applyVo.setUserId(articleApp.getUserId());
        String ordersStatus = applyVo.getOrdersStatus();
        // 发送申请处理结果通知
        extracted(applyVo, ordersStatus, activityArticle);

        return this.updateById(applyVo);
    }

    // 发送申请处理结果通知
    private void extracted(ActivityApplyVo applyVo, String ordersStatus, ActivityArticle activityArticle) {
        if ("5".equals(ordersStatus) || "1".equals(ordersStatus)) {
            // 状态1: 已提交申请, 状态5: 审核通过 - 发送申请结果通知
            sendApplyApplicationResultNotification(applyVo, activityArticle);
        } else if ("3".equals(ordersStatus) || "4".equals(ordersStatus) || "0".equals(ordersStatus)) {
            // 状态3: 审核拒绝, 状态4: 申请退出 - 发送审核结果通知 0 取消申请
            sendApplicationResultNotification(applyVo, activityArticle);
//            sendApplyApplicationResultNotification(applyVo, activityArticle);
        } else if ("2".equals(ordersStatus)) {
            // 状态2: 等待审核 - 发送悬赏文章申请通知给发布者
            sendRewardApplicationNotification(applyVo, activityArticle);
        }
    }

    /**
     * 申请人列表，抵用此接口改为已读状态
     *
     * @param artId
     * @return
     */
    @Override
    public List<ActivityApplyVo> applyList(String artId) {
        return baseMapper.applyList(artId);
    }

    /**
     * 计算已读未读的条数
     *
     * @param artIds
     * @return
     */
    @Override
    public ApplyViewVo appRead(List<String> artIds, String ordersStatus) {
        // 假设 baseMapper 返回的是 List<ApplyViewVo>
        List<ApplyViewVo> applyList = baseMapper.selectBatchArtId(artIds, ordersStatus);

        if (applyList == null || applyList.isEmpty()) {
            return null;
        }
        // 统计已读和未读数量
        long readCount = applyList.stream()
                .filter(apply -> apply.getAppViewStatus() == 1 ||
                        !apply.getOrdersStatus().equals("2"))
                .count();
        long unreadCount = applyList.size() - readCount;
        // 创建汇总结果对象
        ApplyViewVo result = new ApplyViewVo();
        result.setReadCount(readCount);
        result.setUnreadCount(unreadCount);
        return result;
    }

//    // 创建订单
//    private boolean createOrder(ActivityApply article, ActivityArticle activityArticle) {
//        OrderInfoEntityDto orderInfoEntityDto = new OrderInfoEntityDto();
//        orderInfoEntityDto.setPublisherId(activityArticle.getUserId());
//        orderInfoEntityDto.setActivityId(article.getArtId());
//        orderInfoEntityDto.setAcceptorId(article.getUserId());
//        orderInfoEntityDto.setOrderAmount(activityArticle.getMoney());
//        orderInfoEntityDto.setType(activityArticle.getType());
//        return orderInfoService.createOrder(orderInfoEntityDto);
//    }

    /**
     * 处理订单交易状态
     * 根据订单状态执行相应的操作：扣款、打款或退款
     *
     * @param apply         活动申请对象，用于处理订单相关操作
     * @param activityArticle 活动文章对象，包含活动详细信息
     */
    public void processOrderTransaction(ActivityApply apply, ActivityArticle activityArticle, String payPassword, Integer points) {
        log.info("处理订单状态：{}", apply.getOrdersStatus());
        activityArticle.setApplyId(apply.getUserId());
        if (activityArticle.getType() == 1 || activityArticle.getType() == 2) {
            switch (apply.getOrdersStatus()) {
                case "2": // 申请就扣钱 - 扣款
                    // 先修改申请人
                    handleOrderAccepted(apply, activityArticle, payPassword, points);
                    break;
                case "3": // 已完成 - 打款
                    handleOrderCompleted(activityArticle);
                    break;
                case "4": // 已退出 - 退款
                    // 修改状态后续加校验
                    handleOrderCancelled(activityArticle, OrderConstants.ORDER_STATUS_CANCEL,apply);
                    break;
                case "0": // 已退出 - 退款
                    // 修改状态后续加校验
                    handleOrderCancelled(activityArticle, OrderConstants.ORDER_STATUS_CANCEL,apply);
                    break;
                case "1": // 给其他申请人退钱
                    handleOrderOtherApplyRefund(activityArticle, apply.getId());
                    break;
                case "5": // 拒绝 - 退款
                    handleOrderCancelled(activityArticle, OrderConstants.ORDER_STATUS_REFUND,apply);
                    break;
                default:
                    // 对于其他状态，不执行任何操作
                    break;
            }
        }
        log.info("处理订单状态完成");
    }

    /**
     * 处理已接单状态的订单
     * 创建订单并从相应用户扣除款项
     *
     * @param apply         活动申请对象，用于创建订单
     * @param activityArticle 活动文章对象，包含扣款金额和用户信息
     * @throws RuntimeException 如果创建订单失败，则抛出运行时异常
     */
    private void handleOrderAccepted(ActivityApply apply, ActivityArticle activityArticle, String payPassword, Integer points) {
        log.info("处理已接单状态的订单");
        if (activityArticle.getType() == 1) {
            String userId = apply.getUserId();

            BigDecimal amount;
            String userType = "买家";

            log.info("开始扣费，用户ID:{} 扣{}的钱", userId, userType);

            if (userId.isEmpty()) {
                log.info("userId为空");
                throw new CampusException("未找到用户", 201);
            }
            if (payPassword.isEmpty()) {
                throw new CampusException("支付密码不能为空", 201);
            }
            // 校验密码
            boolean isVerified = userService.verifyPassword(userId, payPassword);
            if (!isVerified) {
                throw new CampusException("支付密码错误", 201);
            }
            // 更新订单信息
            amount = calculatePointsAmount(activityArticle, points);
            UpdateWrapper<ActivityApply> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("id", apply.getId());
            updateWrapper.set("pay_amt", amount);
            updateWrapper.set("points", points);
            baseMapper.update(updateWrapper);

            if (amount.compareTo(BigDecimal.ZERO) > 0) {
                boolean isDeducted = userBalanceService.deductBalance(userId, amount);
                if (isDeducted) {
                    UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
                    createAndSaveTransaction(userId, activityArticle.getId(), amount,
                            userBalance.getAvailableAmount().subtract(amount),
                            OrderConstants.TYPE_USER_EXPENSE, "用户预付款",
                            OrderConstants.USER_TYPE_USER, OrderConstants.ORDER_TYPE_PREPAY
                    );
                }

                // 给系统用户加钱
                log.info("开始给系统加钱");
                boolean isAdded = userBalanceService.addBalance(PLATFORM_USER_ID,amount);
                if (isAdded) {
                    UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
                    createAndSaveTransaction(PLATFORM_USER_ID, activityArticle.getId(),
                            amount, platformBalance.getAvailableAmount().add(amount),
                            OrderConstants.TYPE_PLATFORM_INCOME, "用户预付款",
                            OrderConstants.USER_TYPE_PLATFORM, OrderConstants.ORDER_TYPE_PREPAY
                    );
                }
            }
            // 开始扣积分
            if (points > 0) {
                log.info("开始扣积分");
                // 扣积分
                pointsAccountService.minusPoints(userId, points, "积分抵扣");
            }
        }


    }

    public boolean updateOrder(ActivityArticle activityArticle, Integer points, String userId) {
        BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
        if (points != null && points > 0) {
            bountyOrder.setPoints(points);
            BigDecimal pointsAmount = BigDecimal.valueOf(points)   // Convert points to BigDecimal
                    .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);  // Divide by 1000 and round to 2 decimal places
            BigDecimal activityMoney = activityArticle.getMoney().subtract(pointsAmount);
            // 还要判断一下是不是抵扣的超出本身的金额了
            if (activityMoney.compareTo(BigDecimal.ZERO) < 0) {
                throw new CampusException("抵扣积分超出悬赏金额", 201);
            }
            bountyOrder.setBountyAmount(activityMoney.add(pointsAmount));
            bountyOrder.setPointsAmount(pointsAmount);
            bountyOrder.setCashAmount(activityMoney);

        }
        bountyOrder.setAcceptorId(userId);
        bountyOrder.setOrderStatus(OrderConstants.ORDER_STATUS_ACCEPT);
        bountyOrder.setPaymentId(userId);
        bountyOrder.setCreateTime(LocalDateTime.now());
        bountyOrder.setUpdateTime(LocalDateTime.now());
        return bountyOrderService.updateById(bountyOrder);
    }
    // 计算一下积分抵扣金额，返回应付金额
    public BigDecimal calculatePointsAmount(ActivityArticle activityArticle, Integer points) {
        BountyOrder bountyOrder = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
        BigDecimal activityMoney = activityArticle.getMoney();
        if (points != null && points > 0) {
            bountyOrder.setPoints(points);
            BigDecimal pointsAmount = BigDecimal.valueOf(points)   // Convert points to BigDecimal
                    .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);  // Divide by 1000 and round to 2 decimal places
             activityMoney = activityArticle.getMoney().subtract(pointsAmount);
            // 还要判断一下是不是抵扣的超出本身的金额了
            if (activityMoney.compareTo(BigDecimal.ZERO) < 0) {
                throw new CampusException("抵扣积分超出悬赏金额", 201);
            }

        }
       return activityMoney;
    }

    /**
     * 处理已完成状态的订单
     * 向相应用户打款
     *
     * @param activityArticle 活动文章对象，包含打款金额和用户信息
     */

    private void  handleOrderCompleted(ActivityArticle activityArticle) {
        log.info("处理已完成状态的订单");

        UpdateWrapper<BountyOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", activityArticle.getOrderNo());
        if (!activityArticle.getStatus().equals("3")) {
            log.info("发布者没有点击完成，不处理扣钱");
            updateWrapper.set("order_status", OrderConstants.ORDER_STATUS_WAIT_COMPLETE);
            return;
        }
        updateWrapper.set("order_status", OrderConstants.ORDER_STATUS_COMPLETE);
        // 更新订单状态
        bountyOrderService.update(updateWrapper);

        String userId = getRecipientUserId(activityArticle);
        BigDecimal amount = activityArticle.getMoney();
        String userType = activityArticle.getType() == 1 ? "买家" : "卖家";

        log.info("开始打款，给{}打款,用户id{}", userType, userId);

        boolean isAdded = userBalanceService.addBalance(userId, amount);
        if (isAdded) {
            UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
            createAndSaveTransaction(
                    userId,
                    activityArticle.getId(),
                    amount,
                    userBalance.getAvailableAmount().add(amount),
                    OrderConstants.TYPE_USER_INCOME,
                    "用户收款",
                    OrderConstants.USER_TYPE_USER,
                    OrderConstants.ORDER_TYPE_RECEIVE
            );
        }

        // 系统用户扣款
        log.info("开始扣款，给系统扣款");
        boolean isDeducted = userBalanceService.deductBalance(PLATFORM_USER_ID, amount);
        if (isDeducted) {
            UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
            createAndSaveTransaction(
                    PLATFORM_USER_ID,
                    activityArticle.getId(),
                    amount,
                    platformBalance.getAvailableAmount().subtract(amount),
                    OrderConstants.TYPE_PLATFORM_EXPENSE,
                    "用户收款",
                    OrderConstants.USER_TYPE_PLATFORM,
                    OrderConstants.ORDER_TYPE_RECEIVE
            );
        }
        // 处理积分活动
        activityArticleService.handleActivityPoints(activityArticle);
    }

    /**
     * 处理已取消状态的订单
     * 向相应用户退款
     *
     * @param activityArticle 活动文章对象，包含退款金额和用户信息
     */
    private void handleOrderCancelled(ActivityArticle activityArticle, Integer orderStatus,ActivityApply apply) {
        String userId = getRefundUserId(activityArticle);
        BigDecimal amount = activityArticle.getMoney();
        BountyOrder order = bountyOrderService.getByOrderNo(activityArticle.getOrderNo());
        String userType = activityArticle.getType() == 1 ? "卖家" : "买家";
        if (!userId.equals(activityArticle.getApplyId())) {
            log.info("不等于付款人，不处理");
            return;
        }
        log.info("处理已取消状态的订单");
        UpdateWrapper<BountyOrder> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", activityArticle.getOrderNo());
        updateWrapper.set("order_status", orderStatus);
        bountyOrderService.update(updateWrapper);

        log.info("开始退钱，给{}退钱", userId);
       amount = calculatePointsAmount(activityArticle, apply.getPoints());
       if (amount.compareTo(BigDecimal.ZERO) <= 0) {
            log.info("退钱金额小于等于0，不处理");
            return;
        }
        boolean isAdded = userBalanceService.addBalance(userId, amount);
        if (isAdded) {
            UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
            createAndSaveTransaction(
                    userId,
                    activityArticle.getId(),
                    amount,
                    userBalance.getAvailableAmount().add(amount),
                    OrderConstants.TYPE_USER_INCOME,
                    "用户取消申请退钱",
                    OrderConstants.USER_TYPE_USER,
                    OrderConstants.ORDER_TYPE_CANCEL_REFUND
            );
        }

        // 系统用户扣款
        log.info("开始扣款，给系统扣款");
        boolean isDeducted = userBalanceService.deductBalance(PLATFORM_USER_ID, amount);
        if (isDeducted) {
            UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
            boolean isSave = createAndSaveTransaction(
                    PLATFORM_USER_ID,
                    activityArticle.getId(),
                    amount,
                    platformBalance.getAvailableAmount().subtract(amount),
                    OrderConstants.TYPE_PLATFORM_EXPENSE,
                    "用户取消申请退钱",
                    OrderConstants.USER_TYPE_PLATFORM,
                    OrderConstants.ORDER_TYPE_CANCEL_REFUND
            );
            if (!isSave) {
                throw new CampusException("保存交易记录失败", 201);
            }
        }
        if (order.getPoints() != null && order.getPoints() > 0) {
            pointsAccountService.addPoints(userId, order.getPoints(), "用户取消申请退回积分", null);
        }
    }

    /**
     * 处理已取消状态的订单
     * 向相应用户退款
     *
     * @param activityArticle 活动文章对象，包含退款金额和用户信息
     */
    private void handleOrderOtherApplyRefund(ActivityArticle activityArticle, String applyId) {
        log.info("已有人接单，其他申请者退款");
        if (activityArticle.getType() == 1) {
            // 更新订单信息
            ActivityApply apply = baseMapper.selectById(applyId);
            boolean isUpdate =  updateOrder(activityArticle, apply.getPoints(),apply.getUserId());
            if (!isUpdate) {
                log.info("更新订单信息失败,订单号：{}", activityArticle.getOrderNo());
                throw new CampusException("更新订单信息失败", 201);
            }
            List<ActivityApply> list = baseMapper.selectList(new QueryWrapper<ActivityApply>().eq("art_id", activityArticle.getId()).ne("id", applyId));
            if (list.isEmpty()) {
                return;
            }
            list.forEach(item -> {
                String userId = item.getUserId();
                log.info("已有人接单，给{}退钱", userId);
                BigDecimal amount = item.getPayAmt();
                boolean isAdded = userBalanceService.addBalance(userId, amount);
                if (isAdded) {
                    UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
                    createAndSaveTransaction(
                            userId,
                            activityArticle.getId(),
                            amount,
                            userBalance.getAvailableAmount().add(amount),
                            OrderConstants.TYPE_USER_INCOME,
                            "发布人拒绝申请退钱",
                            OrderConstants.USER_TYPE_USER,
                            OrderConstants.ORDER_TYPE_CANCEL_REFUND
                    );
                }

                // 系统用户扣款
                log.info("开始扣款，给系统扣款");
                boolean isDeducted = userBalanceService.deductBalance(PLATFORM_USER_ID, amount);
                if (isDeducted) {
                    UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(PLATFORM_USER_ID);
                    boolean isSave = createAndSaveTransaction(
                            PLATFORM_USER_ID,
                            activityArticle.getId(),
                            amount,
                            platformBalance.getAvailableAmount().subtract(amount),
                            OrderConstants.TYPE_PLATFORM_EXPENSE,
                            "发布人拒绝申请退钱",
                            OrderConstants.USER_TYPE_PLATFORM,
                            OrderConstants.ORDER_TYPE_CANCEL_REFUND
                    );
                    if (!isSave) {
                        throw new CampusException("保存交易记录失败", 201);
                    }
                }
                // 积分退回
                if (item.getPoints() != null && item.getPoints() > 0) {
                    pointsAccountService.addPoints(userId, item.getPoints(), "发布人拒绝申请退回积分", null);
                }

            });
        }

    }

    // 公共方法：创建并保存交易记录
    private boolean createAndSaveTransaction(String userId, String txId, BigDecimal changeAmount, BigDecimal balanceAfterChange,
                                             String txType, String remark, String userType, String type) {
        log.info("开始保存交易记录，用户id{},业务id{},交易类型{}，用户类型{}", userId, txId, txType, userType);
        UserBalanceTransactionEntity transaction = new UserBalanceTransactionEntity();
        transaction.setUserId(userId);
        transaction.setTxId(userType.equals(OrderConstants.USER_TYPE_PLATFORM) ? "PL" + txId : txId);
        transaction.setChangeAmount(changeAmount);  // 微信单位为分
        transaction.setBalanceSnapshot(balanceAfterChange);
        transaction.setTxStatus(OrderConstants.TX_STATUS_SUCCESS);
        transaction.setTxType(txType);
        transaction.setRemark(remark);
        transaction.setUserType(userType);
        transaction.setType(type);
        boolean result = userBalanceTransactionService.save(transaction);
        log.info("保存交易结果：{}", result ? "成功" : "失败");
        return result;
    }

    /**
     * 获取扣款用户的ID
     * 根据活动类型判断是卖家还是买家
     *
     * @param activityArticle 活动文章对象，包含用户ID和活动类型
     * @return 扣款用户的ID
     */
    private String getDeductUserId(ActivityArticle activityArticle) {
        return activityArticle.getType() == 1 ? activityArticle.getApplyId() : activityArticle.getUserId();
    }

    /**
     * 获取收款用户的ID
     * 根据活动类型判断是买家还是卖家
     *
     * @param activityArticle 活动文章对象，包含用户ID和活动类型
     * @return 收款用户的ID
     */
    private String getRecipientUserId(ActivityArticle activityArticle) {
        return activityArticle.getType() == 1 ? activityArticle.getUserId() : activityArticle.getApplyId();
    }

    /**
     * 获取退款用户的ID
     * 根据活动类型判断是卖家还是买家
     *
     * @param activityArticle 活动文章对象，包含用户ID和活动类型
     * @return 退款用户的ID
     */
    private String getRefundUserId(ActivityArticle activityArticle) {
        return activityArticle.getType() == 1 ? activityArticle.getApplyId() : activityArticle.getUserId();
    }

    @Async
    public void saveMessage(String bizId, String applyUserId, String userId) {
        // 获取会话id
        String conversationId = chatConversationService.getConversation(userId, applyUserId).getId();
        // 保存消息
        ChatMessagesEntity entity = new ChatMessagesEntity();
        entity.setBizId(bizId);
        entity.setConversationId(conversationId);
        UserEntity user = userService.getById(applyUserId);
        entity.setFormUserId(applyUserId);
        entity.setToUserId(userId);
        entity.setPostMessages(user.getUserName() + "请求申请悬赏");
        entity.setMsgStatus(ChatMessageConstant.MESSAGE_STATUS_UNREAD); // 默认未读
        entity.setTime(LocalDateTime.now());
        entity.setMessagesType(ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_APPLY);
        entity.setType("0"); // 默认为文本消息
        boolean isSave = chatMessagesService.save(entity);
        if (!isSave) {
            log.error("保存申请消息失败");
            return;
        }
        // 更新会话最后聊天id
        chatConversationService.updateLastMessageId(conversationId, entity.getId(), applyUserId);
        // 构建响应JSON
        JSONObject resJson = buildResponseJson(applyUserId, entity);
        JSONObject toResJson = buildResponseJson(userId, entity);


        // 给某个用户发消息
        WebSocketChatService.sendMessageToUserId(userId, toResJson.toJSONString());
        WebSocketChatService.sendMessageToUserId(applyUserId, resJson.toJSONString());

        // 在重新发一个列表
        sendChatConversationList(applyUserId, "1");
        sendChatConversationList(userId, "0");

        // 发送导航红点消息
        redDotService.sendRedDot(userId);
        redDotService.sendRedDot(applyUserId);
    }

    /**
     * 处理申请人信用值
     * 3分钟后退出-1； 超时-0.2 每超10分钟再-0.1 最多-1
     * 完成+0.5
     *
     * @param applyVo
     * @param article
     * @param activityArticle
     */
    private void handlerCreditValue(ActivityApply applyVo, ActivityApply article, ActivityArticle activityArticle) {
        log.info("开始处理申请人信用值");

        // 接单时间
        LocalDateTime acceptedAt = article.getAcceptedAt();
        // 活动结束时间
        LocalDateTime endTime = activityArticle.getEndTime();

        // 当前时间（完成订单时间 or 退出订单时间）
        LocalDateTime current = LocalDateTime.now();
        UserEntity user = userService.getById(applyVo.getUserId());
//        Double creditValue = user.getCreditValue();
        Double creditChange = 0.0;
        // 统一状态 3-已完成 5-待完成
        String orderStatus = "0";
        if (applyVo.getOrdersStatus().equals("3") || activityArticle.getStatus().equals("3")) {
            orderStatus = applyVo.getOrdersStatus().equals("3") && activityArticle.getStatus().equals("3") ? "3" : "5";
        } else if (applyVo.getOrdersStatus().equals("4")) {
            orderStatus = "4";
        }
        switch (orderStatus) {
            case "3":  // 已完成
                if (isCompletedOnTime(current, endTime)) {
                    // 按时完成
                    creditChange = 0.0;
                    // 给发布人加 加权分

                    log.info("开始给发布人加 加权分");
                    userScoreService.updateMonthlyCreditIncrement(activityArticle.getUserId(), CREDIT_INCREMENT);
                    return;

                } else {
                    // 超时完成
//                    Long overTime = calculateMinutesSinceAccept(endTime, current) / 10;
//                    if (calculateMinutesSinceAccept(endTime, current) == 0) {
//                        creditChange = TIMEOUT_PENALTY;
//                    } else {
//                        double penalty = TIMEOUT_PENALTY + (overTime * LATE_QUIT_PENALTY);
//                        creditChange = penalty <= -1.0 ? -1.0 : penalty;
//                    }
                    creditChange = 0.0;
                }
                break;

            case "4": // 已退出
//                creditChange = calculateMinutesSinceAccept(acceptedAt, current) >= 3 ? EARLY_QUIT_PENALTY : 0.0;
                // 接单时间到退出时间的时间间隔
                Long quitTimeSpan = calculateMinutesSinceAccept(acceptedAt, current);
                // 退出时间到截止时间的时间间隔
                Long quitToEndTimeSpan = calculateMinutesSinceAccept(current, endTime);
                log.info("退出时间间隔：" + quitTimeSpan + " 退出时间到截止时间间隔：");
                if (quitTimeSpan >= 3 && quitToEndTimeSpan >= 180) {
                    creditChange = EARLY_QUIT_PENALTY;
                    log.info("中途退出{}", creditChange);
                } else if (quitToEndTimeSpan < 180) {
                    log.info("中途退出{}", creditChange);
                    creditChange = END_QUIT_PENALTY;
                }
                userScoreService.updateCreditWeight(UserContext.getUser().getId(), creditChange);
                break;
            default:
                break;
        }
//        creditValue += creditChange;
//        if (creditValue > 5.0) {
//            creditValue = 5.0;
//        } else if (creditValue < 0.0) {
//            creditValue = 0.0;
//        }
//        user.setCreditValue(creditValue);
//        userService.updateById(user);


    }

    /**
     * 判断订单是否按时完成
     *
     * @param current
     * @param endTime
     * @return true 按时完成  false 未按时完成
     */
    private static boolean isCompletedOnTime(LocalDateTime current, LocalDateTime endTime) {

        return !current.isAfter(endTime);
    }

    // 计算从接单开始到现在的时间
    private static Long calculateMinutesSinceAccept(LocalDateTime acceptedAt, LocalDateTime current) {
        if (Duration.between(acceptedAt, current).toMinutes() < 0) {
            return Duration.between(acceptedAt, current).toMinutes() * -1;
        }
        return Duration.between(acceptedAt, current).toMinutes();
    }

    public static void main(String[] args) {
        System.out.println(LocalDateTime.now());
        System.out.println(LocalDateTime.now().plusMinutes(1));
        System.out.println(calculateMinutesSinceAccept(LocalDateTime.now(), LocalDateTime.now().plusHours(3)));
    }


    private JSONObject buildResponseJson(String userId, ChatMessagesEntity entity) {
        JSONObject resJson = new JSONObject();
        ChatMessageVo vo = chatMessagesService.convertToDTO(entity);
        vo.setSender(entity.getFormUserId().equals(userId));
        resJson.put("type", "send");
        resJson.put("message", vo);
        resJson.put("conversationId", entity.getConversationId());
        return resJson;
    }

    @Async
    protected void sendChatConversationList(String userId, String type) {
        List<ConversationDto> conversations = chatConversationService.getUserConversations(userId);
        JSONObject result = new JSONObject();
        result.put("type", "messageList");
        result.put("conversations", conversations);
        int unreadCount = 0;
        if ("0".equals(type)) {  // 发布者
            unreadCount = Math.toIntExact(chatMessagesService.count(new QueryWrapper<ChatMessagesEntity>().eq("to_user_id", userId).eq("msg_status", ChatMessageConstant.MESSAGE_STATUS_UNREAD)));
            log.info("发布者条数：{}", unreadCount);
        } else {// 申请者
            unreadCount = Math.toIntExact(chatMessagesService.count(new QueryWrapper<ChatMessagesEntity>().eq("form_user_id", userId).eq("msg_status", ChatMessageConstant.MESSAGE_STATUS_UNREAD)));
            log.info("申请者条数：{}", unreadCount);
        }
        result.put("unreadNum", unreadCount);
        WebSocketChatService.sendMessageToUserId(userId, result.toJSONString());
    }

    @Override
    public List<ActivityApply> getApplyListByArticleIds(List<String> articleIds) {
        QueryWrapper<ActivityApply> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("art_id", articleIds);
        return baseMapper.selectList(queryWrapper);
    }


    /**
     * 发送系统通知给指定用户
     */
    @Async
    @Override
    public void sendSystemNotification(String userId, String title, String content, String type, String artInfo) {
        log.info("准备发送系统通知给用户: {}", userId);

        //存储通知到数据库
        SysNotification notification = new SysNotification();
        notification.setId(RandomUtil.generateId());
        notification.setSenderId("0000");
        notification.setRecipientId(userId);
        notification.setTitle(title);
        notification.setContent(content);
        notification.setType(type); // 系统通知类型
        notification.setStatus("1"); // 已发送
        notification.setCreateTime(LocalDateTime.now());
        notification.setArtInfo(artInfo.isEmpty() ? "{}" : artInfo);
        notificationService.save(notification);

        //通知消息
        JSONObject message = new JSONObject();
        message.put("type", "sysNoticeNumMessage");
        message.put("noticeNum", notificationService.count(new QueryWrapper<SysNotification>().eq("recipient_id", userId).eq("msg_status", "2")));
        WebSocketChatService.sendMessageToUserId(userId, message.toJSONString());

        // 红点消息
        redDotService.sendRedDot(userId);

    }

    /**
     * 发送悬赏文章申请通知(通知发布者)
     */
    public void sendRewardApplicationNotification(ActivityApply apply, ActivityArticle activity) {
        String content;
        if (Objects.equals(activity.getOrdersType(), "1")) {
            content = getUserNickname(apply.getUserId()) + "加入了您的悬赏任务";
        } else {
            content = getUserNickname(apply.getUserId()) + "申请加入您的悬赏任务";
        }
        ArtInfoDto artInfo = getArtInfoDto(apply, activity, true);
        sendSystemNotification(activity.getUserId(), "申请加入悬赏", content, "3", JSON.toJSONString(artInfo));
    }

    // 构建文章信息 存到通知中
    @NotNull
    private ArtInfoDto getArtInfoDto(ActivityApply apply, ActivityArticle activity, boolean isMyRelease) {
        ArtInfoDto artInfo = new ArtInfoDto();
        artInfo.setTitle(activity.getTitle());
        artInfo.setArticleId(activity.getId());
        artInfo.setType(activity.getType());
        artInfo.setIsMyRelease(isMyRelease);
        if (apply.getUserId() != null) {
            artInfo.setApplyId(apply.getId());
            artInfo.setApplyUserName(getUserNickname(apply.getUserId()) == null ? "" : getUserNickname(apply.getUserId()));
            artInfo.setApplyUserAvatar(getUserAvatar(apply.getUserId()) == null ? "" : getUserAvatar(apply.getUserId()));
        }
        artInfo.setArticleUserName(getUserNickname(activity.getUserId()));
        artInfo.setArticleUserAvatar(getUserAvatar(activity.getUserId()));
        return artInfo;
    }

    /**
     * 发送申请处理结果通知(通知申请者)
     */
    public void sendApplyApplicationResultNotification(ActivityApplyVo applyVo, ActivityArticle article) {
        String content;
        String type = "4";
        String title = "悬赏任务已同意";
        boolean isMyRelease = false;
        //订单状态：1：已接单；2未接单；3：已完成；4：已退出；5: 已拒绝
        String result = switch (applyVo.getOrdersStatus()) {
            case "1" -> "同意";
            case "3" -> "已完成";
            case "5" -> "拒绝";
            default -> null;
        };
        if (article.getStatus().equals("3")) {
            content = "您申请的悬赏任务——" + "“" + result + "”";
            type = "2";
            title = "悬赏任务已完成";
            if (applyVo.getOrdersStatus().equals("1")) {
                content = "您申请的悬赏任务——" + "“待确认”";
                type = "1";
                title = "悬赏任务待确认";
            }
        } else {
            if (applyVo.getOrdersStatus().equals("5")) {
                type = "5";
                title = "悬赏任务已拒绝";
            }
//            if (applyVo.getOrdersStatus().equals("4")) {
//                type = "4";
//                title = "悬赏任务已退出";
//            }
            content = getUserNickname(article.getUserId()) + result + "了你的申请";
        }
        ArtInfoDto artInfo = getArtInfoDto(applyVo, article, isMyRelease);
        sendSystemNotification(applyVo.getUserId(), title, content, type, JSON.toJSONString(artInfo));
    }

    /**
     * 发送申请处理结果通知(通知发布者)
     */
    public void sendApplicationResultNotification(ActivityApplyVo applyVo, ActivityArticle article) {
        //订单状态：1：已接单；2未接单；3：已完成；4：已退出；5: 已拒绝
        String result = switch (applyVo.getOrdersStatus()) {
            case "3" -> "已完成";
            case "4" -> "已退出";
            case "0" -> "已取消";
            default -> null;
        };
        if (result == null) {
            return;
        }
        String contentS = null;
        String type = "";
        String title = "";
        if (applyVo.getOrdersStatus().equals("4")) {
            contentS = getUserNickname(applyVo.getUserId()) + "退出了您的悬赏任务";
//            contentS = "您发布的悬赏任务——" + "“" + result + "”";
            type = "8";
            title = "退出悬赏任务";
        } else if (applyVo.getOrdersStatus().equals("0")) {
            contentS = getUserNickname(applyVo.getUserId()) + "取消了您的悬赏任务";
            type = "9";
            title = "取消悬赏任务";
        } else if (article.getStatus().equals("3")) {
            type = "2";
            contentS = "您发布的悬赏任务——" + "“" + result + "”";
            title = "完成悬赏任务";
        } else if (article.getStatus().equals("1")) {
            type = "1";
            contentS = "您发布的悬赏任务——" + "“待确认”";
            title = "待确认悬赏任务";
        }
        if (contentS != null) {
            ArtInfoDto artInfo = getArtInfoDto(applyVo, article, true);
            sendSystemNotification(article.getUserId(), title, contentS, type, JSON.toJSONString(artInfo));
        }
    }

    // 获取用户名称
    @Override
    public String getUserNickname(String userId) {
        UserEntity user = userService.getById(userId);
        if (user.getUserName() == null) {
            return user.getRealName();
        }
        return user.getUserName();
    }

    // 获取用户头像
    @Override
    public String getUserAvatar(String userId) {
        UserEntity user = userService.getById(userId);
        return user.getAvatarUrl();
    }

    public int isFirstApply(String applyUserId) {
        return baseMapper.isFirstApply(applyUserId);
    }
}
